package com.xpxrule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xpxrule.dataobject.biz.model.ReturnResponse;
import com.xpxrule.dataobject.dao.BusinessModel;
import com.xpxrule.dataobject.dao.ModelItem;
import com.xpxrule.dataobject.dao.RuleScenarios;
import com.xpxrule.dataobject.req.RuleScenariosQueryReq;
import com.xpxrule.dataobject.vo.OptionVo;
import com.xpxrule.dataobject.vo.RuleScenariosVo;
import com.xpxrule.mapper.RuleScenariosMapper;
import com.xpxrule.service.BusinessModelService;
import com.xpxrule.service.ModelItemService;
import com.xpxrule.service.RuleScenariosService;
import com.xpxrule.util.ModelConvertUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RuleScenariosServiceImpl implements RuleScenariosService {
    @Autowired
    private RuleScenariosMapper ruleScenariosMapper;
    @Autowired
    private BusinessModelService businessModelService;
    @Autowired
    private ModelItemService modelItemService;
    @Override
    public ReturnResponse insert(RuleScenariosVo vo) {
        boolean isExist = verifyDbUnique(vo);
        if (!isExist) {
            return ReturnResponse.fail("The unique verification failed. The new data already exists in the database.");
        }
        // todo 校验条件模型及结果模型
        RuleScenarios ruleScenarios = ModelConvertUtil.convertRuleScenariosVoToRuleScenarios(vo);
        int count = ruleScenariosMapper.insert(ruleScenarios);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse delete(Long id) {
        boolean isExist = verifyDbExistById(id);
        if (!isExist) {
            return ReturnResponse.fail("The data does not exist in the database.");
        }
        RuleScenarios ruleScenarios = ruleScenariosMapper.selectById(id);
        ruleScenarios.setIsDeleted(new Date());
        int count = ruleScenariosMapper.updateById(ruleScenarios);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse update(RuleScenariosVo vo) {
        boolean isExist = verifyDbExistById(Long.valueOf(vo.getId()));
        if (!isExist) {
            return ReturnResponse.fail("The data does not exist in the database.");
        }
        RuleScenarios old = ruleScenariosMapper.selectById(vo.getId());
        ModelConvertUtil.fillRuleScenariosFromRuleScenariosVo(old, vo);
        int count = ruleScenariosMapper.updateById(old);
        return ReturnResponse.success(count);
    }

    @Override
    public ReturnResponse<List<RuleScenariosVo>> selectList(RuleScenariosQueryReq req) {
        List<RuleScenarios> list = selectRuleScenariosListByReq(req);
        List<RuleScenariosVo> reulstList = list.stream().map(ModelConvertUtil::convertRuleScenariosToRuleScenariosVo)
                .collect(Collectors.toList());
        return new ReturnResponse<>(reulstList);
    }

    private List<RuleScenarios> selectRuleScenariosListByReq(RuleScenariosQueryReq req) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(req.getScenariosKey())) {
            wrapper.like(RuleScenarios.COLUMN.SCENARIOS_KEY, req.getScenariosKey());
        }
        if (!StringUtils.isEmpty(req.getScenariosName())) {
            wrapper.like(RuleScenarios.COLUMN.SCENARIOS_NAME, req.getScenariosName());
        }
        if (!ObjectUtils.isEmpty(req.getIsEnable())) {
            wrapper.eq(RuleScenarios.COLUMN.IS_ENABLE, req.getIsEnable());
        }
        wrapper.isNull(RuleScenarios.COLUMN.IS_DELETED);
        return ruleScenariosMapper.selectList(wrapper);
    }

    @Override
    public List<ModelItem> getConditionModelByScenariosKey(String ruleScenariosKey) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        wrapper.eq(RuleScenarios.COLUMN.SCENARIOS_KEY, ruleScenariosKey);
        List<RuleScenarios> list = ruleScenariosMapper.selectList(wrapper);
        if (list.isEmpty()) {
            // todo 报错
        }
        RuleScenarios ruleScenarios = list.get(0);
        String conditionModel = ruleScenarios.getConditionModel();
        // 根据业务模型key查询业务模型
        // 获取明细字段
        List<ModelItem> modelItemList = modelItemService.getModelItemsByModelKey(conditionModel);
        return modelItemList;
    }

    @Override
    public ReturnResponse<List<OptionVo>> getAllRuleScenariosOptions() {
        RuleScenariosQueryReq req = new RuleScenariosQueryReq();
        req.setIsEnable((short) 0);
        List<RuleScenarios> list = selectRuleScenariosListByReq(req);
        List<OptionVo> resultList = list.stream()
                .map(ModelConvertUtil::convertRuleScenariosToOptionVo)
                .collect(Collectors.toList());
        return new ReturnResponse<>(resultList);
    }

    @Override
    public ReturnResponse<RuleScenariosVo> selectRuleScenariosByScenariosKey(String scenariosKey) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        wrapper.eq(RuleScenarios.COLUMN.SCENARIOS_KEY, scenariosKey);
        wrapper.isNull(RuleScenarios.COLUMN.IS_DELETED);
        wrapper.eq(RuleScenarios.COLUMN.IS_ENABLE, (short) 0);
        List<RuleScenarios> list = ruleScenariosMapper.selectList(wrapper);
        if (list == null || list.size() != 1) {
            System.out.println("查询数据异常");
        }
        RuleScenariosVo vo = ModelConvertUtil.convertRuleScenariosToRuleScenariosVo(list.get(0));
        return new ReturnResponse<>(vo);
    }

    @Override
    public RuleScenarios getRuleScenariosByScenariosKey(String scenariosKey) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        wrapper.eq(RuleScenarios.COLUMN.SCENARIOS_KEY, scenariosKey);
        wrapper.isNull(RuleScenarios.COLUMN.IS_DELETED);
        List<RuleScenarios> list = ruleScenariosMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list) || list.size() != 1) {
            throw new RuntimeException("The data does not exist in the database.");
        }
        return list.get(0);
    }

    private boolean verifyDbExistById(Long id) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        wrapper.eq(RuleScenarios.COLUMN.ID, id);
        wrapper.isNull(RuleScenarios.COLUMN.IS_DELETED);
        Long count = ruleScenariosMapper.selectCount(wrapper);
        return count == 1;
    }

    private boolean verifyDbUnique(RuleScenariosVo vo) {
        QueryWrapper<RuleScenarios> wrapper = new QueryWrapper<>();
        wrapper.eq(RuleScenarios.COLUMN.SCENARIOS_KEY, vo.getScenariosKey());
        wrapper.isNull(RuleScenarios.COLUMN.IS_DELETED);
        Long count = ruleScenariosMapper.selectCount(wrapper);
        return count == 0;
    }
}
